package asm;

import org.ricks.asm.*;

/**
 * @author chenwei
 * @date 2022/9/1513:41
 */
public class DispacherDump implements Opcodes {

    public static byte[] dump() throws Exception {

        ClassWriter classWriter = new ClassWriter(0);
        FieldVisitor fieldVisitor;
        MethodVisitor methodVisitor;

        classWriter.visit(V17, ACC_PUBLIC | ACC_SUPER, "app/dispacher/Dispacher", null, "java/lang/Object", null);

        classWriter.visitSource("Dispacher.java", null);

        {
            fieldVisitor = classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "dispacher", "Lapp/dispacher/Dispacher;", null, null);
            fieldVisitor.visitEnd();
        }
        {
            methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            methodVisitor.visitCode();
            Label label0 = new Label();
            methodVisitor.visitLabel(label0);
            methodVisitor.visitLineNumber(12, label0);
            methodVisitor.visitVarInsn(ALOAD, 0);
            methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
            methodVisitor.visitInsn(RETURN);
            Label label1 = new Label();
            methodVisitor.visitLabel(label1);
            methodVisitor.visitLocalVariable("this", "Lapp/dispacher/Dispacher;", null, label0, label1, 0);
            methodVisitor.visitMaxs(1, 1);
            methodVisitor.visitEnd();
        }
        {
            methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "getMethodFunction", "(Lorg/demon/common/Context;)V", "(Lorg/demon/common/Context<Ljava/lang/Short;[Ljava/lang/Byte;>;)V", null);
            methodVisitor.visitParameter("context", 0);
            methodVisitor.visitCode();
            Label label0 = new Label();
            methodVisitor.visitLabel(label0);
            methodVisitor.visitLineNumber(18, label0);
            methodVisitor.visitVarInsn(ALOAD, 1);
            methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/ricks/common/Context", "getCmd", "()Ljava/lang/Object;", false);
            methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/Short");
            methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
            Label label1 = new Label();
            Label label2 = new Label();
            Label label3 = new Label();
            methodVisitor.visitLookupSwitchInsn(label3, new int[]{1, 2}, new Label[]{label1, label2});
            methodVisitor.visitLabel(label1);
            methodVisitor.visitLineNumber(20, label1);
            methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            methodVisitor.visitLdcInsn(Type.getType("Lapp/controller/TestController;"));
            methodVisitor.visitMethodInsn(INVOKESTATIC, "org/ricks/ioc/ApplicationContext", "getBean", "(Ljava/lang/Class;)Ljava/lang/Object;", false);
            methodVisitor.visitTypeInsn(CHECKCAST, "app/controller/TestController");
            methodVisitor.visitVarInsn(ALOAD, 1);
            methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "app/controller/TestController", "test", "(Lorg/demon/common/Context;)V", false);
            methodVisitor.visitLabel(label2);
            methodVisitor.visitLineNumber(22, label2);
            methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            methodVisitor.visitLdcInsn(Type.getType("Lapp/controller/TestController;"));
            methodVisitor.visitMethodInsn(INVOKESTATIC, "org/ricks/ioc/ApplicationContext", "getBean", "(Ljava/lang/Class;)Ljava/lang/Object;", false);
            methodVisitor.visitTypeInsn(CHECKCAST, "app/controller/TestController");
            methodVisitor.visitVarInsn(ALOAD, 1);
            methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "app/controller/TestController", "testUserDb", "(Lorg/demon/common/Context;)V", false);
            methodVisitor.visitLabel(label3);
            methodVisitor.visitLineNumber(24, label3);
            methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            methodVisitor.visitInsn(RETURN);
            Label label4 = new Label();
            methodVisitor.visitLabel(label4);
            methodVisitor.visitLocalVariable("this", "Lapp/dispacher/Dispacher;", null, label0, label4, 0);
            methodVisitor.visitLocalVariable("context", "Lorg/demon/common/Context;", "Lorg/demon/common/Context<Ljava/lang/Short;[Ljava/lang/Byte;>;", label0, label4, 1);
            methodVisitor.visitMaxs(2, 2);
            methodVisitor.visitEnd();
        }
        {
            methodVisitor = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
            methodVisitor.visitCode();
            Label label0 = new Label();
            methodVisitor.visitLabel(label0);
            methodVisitor.visitLineNumber(14, label0);
            methodVisitor.visitTypeInsn(NEW, "app/dispacher/Dispacher");
            methodVisitor.visitInsn(DUP);
            methodVisitor.visitMethodInsn(INVOKESPECIAL, "app/dispacher/Dispacher", "<init>", "()V", false);
            methodVisitor.visitFieldInsn(PUTSTATIC, "app/dispacher/Dispacher", "dispacher", "Lapp/dispacher/Dispacher;");
            methodVisitor.visitInsn(RETURN);
            methodVisitor.visitMaxs(2, 0);
            methodVisitor.visitEnd();
        }
        classWriter.visitEnd();

        return classWriter.toByteArray();
    }
}